#include "msg_port_drv.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

msg_port_t g_tMsgPortList;


void msg_port_Init(void)
{
	memset(&g_tMsgPortList, 0, sizeof(msg_port_t));
}

static void msg_port_list_add(msg_port_t *msg_port)
{	
	msg_port_t *tpMsgPortList = &g_tMsgPortList;

	while(tpMsgPortList->next_MsgPort != NULL)
	{
		tpMsgPortList = tpMsgPortList->next_MsgPort;
	}
	tpMsgPortList->next_MsgPort = msg_port;
	msg_port->next_MsgPort = NULL;
	
}

void msg_port_create(msg_port_t *msg_port,
				  uint8_t (*check_send_state)(struct _msg_port_t *msg_port),
				  void (*uart_write)(struct _msg_port_t *msg_port, uint8_t *str, uint16_t size))
{
	msg_port->State = UART_PORT_READY;
	ringBuff_init(&msg_port->MsgTX_RingBuff);
	ringBuff_init(&msg_port->MsgRX_RingBuff);
	msg_port->check_send_state = check_send_state;
	msg_port->uart_write = uart_write;
	msg_port->next_MsgPort = NULL;
	msg_port_list_add(msg_port);
	return;
}

uint8_t msg_port_RxNoEmpty(msg_port_t *msg_port)
{
  return ringBuff_noEmpty(&msg_port->MsgRX_RingBuff);
}

uint8_t msg_port_RxEnqueue(msg_port_t *msg_port,
						   uint8_t *str,uint16_t size)
{
	uint8_t flag ;
	flag = ringBuff_enqueue(&msg_port->MsgRX_RingBuff,str,size);
	
	if(flag == 0)
		return UART_PORT_ERR;
	
	return UART_PORT_OK;
}

uint8_t msg_port_RxDequeue(msg_port_t *msg_port,
						   uint8_t *msg_buff,
							uint16_t *msg_size)
{
	if(ringBuff_noEmpty(&msg_port->MsgRX_RingBuff) == 0)
		return 0;
	
	ringBuff_dequeue(&msg_port->MsgRX_RingBuff,msg_buff,msg_size);
  return 1;
}


void msg_port_handle(msg_port_t *msg_port)
{
  
	uint16_t	  		msg_size;

	if(msg_port->State == UART_PORT_BUSY)
	{
		if(msg_port->check_send_state(msg_port))
		{
			msg_port->State = UART_PORT_READY;
		}
		else
		{
			return ;
		}
	}
	
	if(ringBuff_noEmpty(&msg_port->MsgTX_RingBuff) == 0)
		return ;
  
	ringBuff_dequeue(&msg_port->MsgTX_RingBuff, msg_port->msg_buff, &msg_size);
	msg_port->uart_write(msg_port,  msg_port->msg_buff, msg_size);
	
	msg_port->State = UART_PORT_BUSY;
}


uint8_t msg_port_send(msg_port_t *msg_port,
					  uint8_t *str,
					  uint16_t size)
{
	uint8_t flag ;

	flag = ringBuff_enqueue(&msg_port->MsgTX_RingBuff,str,size);
	
	if(flag == 0)
		return UART_PORT_ERR;
	
  #if  MSG_PORT_USE_DMA
    msg_port_handle(msg_port);
  #endif
  
	return UART_PORT_OK;
}

void msg_ports_traverse(void)
{
	msg_port_t *tpMsgPortList = &g_tMsgPortList;

	while(tpMsgPortList->next_MsgPort != NULL)
	{
		tpMsgPortList = tpMsgPortList->next_MsgPort;
		msg_port_handle(tpMsgPortList);
	}

}
